#!/usr/bin/python


import random
#from constants import *
from time import strftime

import logging



# Own constants
TREE_ID = "http://nepomuk.semanticdesktop.org"
logger = logging.getLogger("pyfuncs")
logger.setLevel(logging.DEBUG+1)


def random_string(nb_chars):
	""" Returns a random string of nb_chars alphanumeric characters.
		:Parameters:
			`nb_chars` : int
				The wanted number of characters in the result string.
		:Returns: The wanted random string - str.
	"""
	string = ""
	for i in range(nb_chars):
		string += random.choice("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
	return string
	
############################################################

def node2string(node):
	""" Returns a string representation of the given node (similar to the ones used by sopranocmd).
		:Parameters:
			`node` : a dbus.node
				The node that we want string-represented.
		:Returns: The wanted string.
	"""
	
	if node[0] == NODE_EMPTY:
		return "(empty)"
	elif node[0] == NODE_RESOURCE:
		return "<" + node[1] + ">"
	elif node[0] == NODE_LITERAL:
		return "\"" + node[1] + "\"^^" + node[3]
	elif node[0] == NODE_BLANK:
		return "_:"+node[1]

############################################################

def makeOntologyUriFromUserId(user_id, ontology_name):
	""" Returns the ontology URI built using the user_id and the ontology name.
		:Parameters:
			`user_id` : str
				The identifier of the user. This is not very well defined at this time, but could be something like an email address or jabber account.
			`ontology_name` : str
				The name of the ontology.
		:Returns: The wanted URI - str.
	"""
	
	return "nepomuk:" + user_id + "/resources/ontologies/" + ontology_name

# This import is located here because contants.py needs the makeOntologyUriFromUserId() function.
from constants import *

############################################################

def makeUriWithUserId(user_id, resource_name):
	""" Returns a URI composed of the user_id and the resource_name to identify a resource.
		:Parameters:
			`user_id` : str
				The identifier of the user.
			`resource_name` : str
				The name of the considered resource.
		:Returns: The wanted URI - str.
	"""
	
	return "nepomuk:" + user_id + "/resources/pimo/" + resource_name

############################################################

def getDateTime():
	""" A simple format of the current time.
		:Returns: The time formatted - str.
	"""
	
	return strftime("%Y-%m-%dT%H:%M:%S%Z")
	# see http://www.w3.org/TR/xmlschema-2/#dateTime for details about the standard format, and http://docs.python.org/lib/module-time.html for the python strftime function and others.
	
############################################################

# 
def kill_spaces(user_formatted_name):
	""" Turns a "user-formatted" name (with spaces) into its equivalent in "uri-formatted" name, e.g. kill_spaces("is supervised by") will return "isSupervisedBy"
		:Parameters:
			`user_formatted_name` : str
				The name provided by the user (may contain spaces).
		:Returns: The "URI-formatted" string - str.
	"""
	
	st = "".join(	user_formatted_name.title().split(" ") )
	st = st[0].lower()+st[1:len(st)]
	return st

############################################################

def getRealPageTitle(page_title):
	""" Just removes the "Mozilla Firefox" part of a web page title.
		:Parameters:
			`page_title` : str
				The title of a page in the Firefox way.
		:Returns: The wanted page title - str.
	"""
	
	index = page_title.find(" - Mozilla Firefox")
	if index != -1:
		return page_title[0:index]
	else:
		return page_title

############################################################

# gets the ending part of long_name, the one located after the '#' character.
def getName(long_name):
	# TODO: delete this function
	
	sharp_index = long_name.rfind("#")
	if sharp_index == -1:
		return long_name
	else:
		return long_name[sharp_index+1:len(long_name)]

############################################################

def makeExistenceWhereClause(resource, relation, object):
	""" Builds up an "existence where clause". This is due to a lack in soprano, which does not seem to be able to say if a precise statement exists or not. This is just a trick to be able to ask for it.
		:Parameters:
			`resource` : str
				The URI of the resource, first node of the statement.
			`relation` : str
				The URI of the relation, second node of the statement.
			`object` : str
				The URI of the object, third node of the statement.
		:Returns: The where clause that can be inserted in a SPARQL request, like "SELECT * WHERE " + makeExistenceWhereClause(...).
	"""
	
	st = "{ "
	st += "<" + resource + "> ?relation <" + object + "> "
	st += "FILTER (?relation = <"+relation+">) "
	st += "}"
	return st

############################################################

def bool_expr(var_name, my_set):
	""" Builds up a boolean expression that tests whether var_name corresponds to one of the URIs given in my_set.
		:Parameters:
			`var_name` : str
				The name of the concerned variable.
			`my_set` : set(str)
				The URI of the relation, second node of the statement.
			:Returns: The boolean expression that can be inserted in a SPARQL request, like "SELECT * WHERE { ... FILTER( %s ) }" % bool_expr(...).
	"""
	
	expr = ""
	for elt in my_set:
		expr += "(str(?" + var_name + ") = \"" + elt + "\") || "
	expr += "false"
	
	return expr

############################################################

""" old! (was used to generate a tree in an external file, that can be used to display information in a XUL treeview)
class rdf_gen:
	# The aim of this class is to generate a tree in an external file that will be directly displayed in a XUL treeview. You should not use this class any more, our goal being to avoid the use of the I/O system. Please rather consider to get the results you want directly and treat them graphically yourself.
	
	def __init__(self, file_name):
		self.file = file( file_name, "w" )
		self.tag_group_no = 1

############################################################

	def write_tags(self, tags):
		
		self.footer = ""
		
		current_uri = ""
		self.tag_group_no = 1
		tag_no = -1
		
		self.write_header()
		
		while tags.next():
			uri = tags.current()[0]["uri"][1]
			tag = tags.current()[0]["tag"][1]
			desc = tags.current()[0]["desc"][1]
			
			# information about the uri (if it is new)
			if uri != current_uri:
				
				if tag_no != -1:
					self.register_info_in_footer(tag_no - 1)
					self.tag_group_no += 1
					
				# prepare new information
				current_uri = uri
				#self.file.write("\t<RDF:Description RDF:about=\"" + TREE_ID + "/tag" + str(self.tag_group_no) + "\">\n")
				#self.file.write("\t\t<Annotation:item>" + uri + "</Annotation:item>\n")
				#self.file.write("\t</RDF:Description>\n\n")
				tag_no = 1
				
			# information about the nth tag and description of this tag
			self.file.write("\t<RDF:Description RDF:about=\"" + TREE_ID + "/tag" + str(self.tag_group_no) + "-" + str(tag_no) + "\">\n")
			self.file.write("\t\t<Annotation:item>" + tag + "</Annotation:item>\n")
			self.file.write("\t\t<Annotation:info>" + desc + "</Annotation:info>\n")
			self.file.write("\t</RDF:Description>\n\n")
			
			tag_no += 1
			
			logger.debug(uri)
			logger.debug(tag)
			logger.debug(desc)
		
		if tag_no != -1: # it means that there is not any tag.
			self.register_info_in_footer(tag_no - 1)
		self.write_footer()
		
		self.file.close()
		
############################################################

	def write_header(self):
		self.file.write("<?xml version=\"1.0\"?>\n\n")
		self.file.write("<RDF:RDF xmlns:RDF=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:Annotation=\"" + TREE_ID + "/rdf#\">\n\n")
		
		self.file.write("\t<RDF:Description RDF:about=\"" + TREE_ID + "/tags\">\n")
		self.file.write("\t\t<Annotation:item>" + TREE_ID + "</Annotation:item>\n")
		self.file.write("\t</RDF:Description>\n\n")
		
############################################################

	def write_footer(self):
		#self.file.write("\t<RDF:Seq RDF:about=\"" + TREE_ID + "/all-tags\">\n")
		#self.file.write("\t\t<RDF:li>\n")
		
		self.file.write("\t<RDF:Seq RDF:about=\"" + TREE_ID + "/tags\">\n")

		self.file.write(self.footer)
		
		self.file.write("\t</RDF:Seq>\n\n")
		
		#self.file.write("\t\t</RDF:li>\n")
		#self.file.write("\t</RDF:Seq>\n\n")
		
		self.file.write("</RDF:RDF>\n")
		
############################################################

	def register_info_in_footer(self, nb_tags):
		# register the information for the tree view ("close" the current uri)
		for i in range(nb_tags):
			self.footer += "\t\t\t\t<RDF:li RDF:resource=\"" + TREE_ID + "/tag" + str(self.tag_group_no) + "-" + str(i+1) + "\"/>\n"
			
############################################################

	# An item is a tuple containing the values for one particular piece of information
	def write_list(self, info_type, item_list):
		
		self.footer = ""
		
		# The info_type represents the types of information contained in each item of the item_list, e.g. ["Annotation:item", "Annotation:url"].
		
		item_no = 1
		
		self.write_header()
		
		for item in item_list:
			
			# keys information for the nth element (e.g. tag and description of the current tag
			self.file.write("\t<RDF:Description RDF:about=\"" + TREE_ID + "/tag" + str(item_no) + "\">\n")
			for i in range(len(item)):
				self.file.write("\t\t<" + info_type[i] + ">" + item[i] + "</" + info_type[i] + ">\n")
				#self.file.write("\t\t<Annotation:info>" + desc + "</Annotation:info>\n")
			self.file.write("\t</RDF:Description>\n\n")
			
			#self.register_info_in_footer(tag_no - 1)
			self.footer += "\t\t<RDF:li RDF:resource=\"" + TREE_ID + "/tag" + str(item_no) + "\"/>\n"
			
			item_no += 1
		
		self.write_footer()
		
		self.file.close()
		
		return 0
	
	"""
	
	